package com.changgou.gateway.web.filter;

import com.changgou.gateway.web.service.AuthService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class AuthFilter implements GlobalFilter, Ordered {

    @Autowired
    private AuthService authService;

    private static final String LOGIN_URL = "http://localhost:8001/api/oauth/toLogin";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        //获取request和response对象
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        //获取当前请求的路径
        String path = request.getURI().getPath();

        //登录操作直接放行,无需校验
//        if(path.equals("/api/oauth/login") || path.equals("/api/oauth/toLogin")){
        boolean flag = UrlFilter.hasAuthorize(path);

        if(path.equals("/api/oauth/login") || !flag){
            //放行
            return chain.filter(exchange);
        }

        //从cookie中获取jti
        //null
        String jti = authService.getJtiFromCookie(request);

        //cookie中没有jti,说明没有登录
        if(StringUtils.isEmpty(jti)){
            //拒绝访问,请求跳转到登录页面
//            response.setStatusCode(HttpStatus.UNAUTHORIZED);//401
//            return response.setComplete();
            return this.toLoginPage(LOGIN_URL+"?FROM="+request.getURI(),response);
        }

        //从redis中获取令牌
        String token = authService.getTockenFromRedis(jti);
        if(StringUtils.isEmpty(token)){
            //拒绝访问,请求跳转登录页面
//            response.setStatusCode(HttpStatus.UNAUTHORIZED);//401
//            return response.setComplete();
            return this.toLoginPage(LOGIN_URL,response);
        }

        //网关,不进行令牌的校验,只是对令牌进行基本的获取
        //设置请求头,携带token令牌
        //格式: Authorization=Bearer access_token
        //request.getHeaders().add("Authorization","Bearer "+token);
        request.mutate().header("Authorization","Bearer "+token);
        return chain.filter(exchange);
    }

    /**
     * 用户没有登录,没有获取到令牌,直接跳转到登录页面进行登录操作.
     * @param loginUrl
     * @param response
     * @return
     */
    private Mono<Void> toLoginPage(String loginUrl, ServerHttpResponse response) {
        //通过response对象,设置状态码,
        response.setStatusCode(HttpStatus.SEE_OTHER);//303
        //设置跳转路径
        response.getHeaders().set("Location",loginUrl);
        return response.setComplete();
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
